package edu.psu.geovista.data.model;

import edu.psu.geovista.data.model.filter.AttributeFilter;

import javax.swing.table.TableModel;
import java.util.Vector;
import java.util.Map;
import java.awt.*;
import java.io.File;
/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * Licensed under Simplified BSD License
 *
 * @original author: jin Chen 
 * @author: jin Chen 
 * @date: Jan 23, 2010$
 * @version: 1.0
 */

public interface AppDataModel2 {
    void addColumn(Object colId, Vector column);

    void addColumn(Object colId, Vector column, boolean equalRowCount);

    void setColumn(Object colId, Vector column);

    void insertColumn(int columnIndex,Object colId, Vector column);

    void removeColumn(int index);

    void removeColumn(Object id);

    void setData(Object[] data);

    void setColumnIdentifiers(Object[] colids);

    void setColumnIdentifiers(java.util.List columnIdentifiers);

    void setColumnIdentifiers(Vector columnIdentifiers);

    void setDataVector(Vector dataVector, Vector columnIdentifiers);

    void setColumnIdentifier(int index, Object id);

    Vector<Object> getColumnIdentifiers();

    Vector getColumn(int colIndex);

    Object[] getColumnAsArray(int index);

    Vector getColumn(Object colId);/* public double getColumnMinValue(int column) {

        //float minval = ((float[])values.firstElement())[dimension];
        Double minval = (Double) this.getValueAt(0,column);//initial
        if (Double.isNaN(minval)){
            minval = Double.MAX_VALUE;
        }
        int rowCount = this.getRowCount();
        if(rowCount==1){
            return Math.min(0,minval);
        }
        for (int i=0; i<rowCount; i++){
            //if (((float[])values.elementAt(i))[dimension] < minval) minval = ((float[])values.elementAt(i))[dimension];
            Double f= (Double) this.getValueAt(i,column);
            if (f < minval&&(Double)f!=AppDataModel.NULL_INT )
                minval = f;
        }

        return minval;

    }*/

    double[] getColumnMinMax(int colindex);

    double[] getColumnMinMax(Vector <Number> col);

    String getColumnName(int column);

    String[] getColumnNames();

    Object getColumnId(int column);

    Object[] getColumnIds();

    double[] getColumnValueAsDouble(int column);

    double[] getColumnValueAsDouble(String columnId);

    String[] getColumnNamesNumeric();

    String[] getColumnNamesString();

    String[] getColumnDescription(String[] colnames);

    Class[] getColumnTypes(Object[] colIds);

    Class getColumnType(Object colIds);

    java.util.List<java.util.List> getColumnByType(Class aclass);

    String[] getColumnTypeNames(Object[] colIds);

    void addRow(Object[] row);

    void addRowQuick(Object[] row);

    void addRow(Vector row);

    void addRowQuick(Vector row);

    void removeRow(int row);

    void removeRows(Object IdCol, Object Ids[]);

    void setRowNameColumns(String[] rowNameColumns);

    String[] getRowNameColumns();

    String[] getRownames();

    String[] getRowNames(String[] columnNames,String delimit);

    void setValueAt(Object aValue, int row, int column);

    Object[] getIdValues();/*public double[][] getNumericValues(){
        int[] indexs = this.getIndexsNumericValue();
        int rowCount = this.getRowCount();
        int colCount = indexs.length;

        double[][] result=new double[ colCount][ rowCount]; // a column based matrix
        for (int col =0;col <colCount;col++){
               Vector column = (Vector) dataVector.get(indexs[col]);
               double[] acolumn=new double[0];
            acolumn =  CollectionUtils.convertVectorToDouble(column);//convert2Double(column);
            result[col]=acolumn;
        }
        return result;
    }*/

    Object[] getNumericValues();

    Object[] getNumericDoubleValues();

    Object[] getNumericIntegerValues();

    Object[] getNumericFloatValues();

    Object[] getGeoVistaData4Shp();

    Shape[] getShapeValues();

    double[] getNumericValue(Object colId);

    double[] getNumericValue(int colIndex);

    double getNumericValue(int row, int column);

    double getNumericValue(int row, Object colId);

    Object getValueAt(int row, int column);

    Object getValueAt(int row, Object columnId);



    Object[] getValues(Object  valueColumnId,Object  checkColumnId, Object value);

    Object getValue(Object  valueColumnId,Object  checkColumnId, Object value);

    double[] getRowValueAsDouble(int row);

    String[] getRowValueAsString(int row);

    Vector getRowValues(int row);

    int getRowIndex(Object colId, Object value );

    int[] getRowIndexs(Object colId, Object[] values );

    Vector getRowValues(Object colId, Object value );

    Map<String, Vector> getRowsMap(Object colId, Vector keys);/*public Vector getRow(int row){
        return dataVector.get(row);
    }*/

    int getColumnIndexById(Object id);

    int getColumnIndexByName(String colName);

    int getColumnIndexByNameIgnoreCase(String colName);

    int[] getIndexsNumericValue();

    int[] getIndexsStringValue();

    int[] getIndexsShapeValue();

    int[] getColumnIndexs(Class aclass);

    boolean isNumericColumn(Object colId);

    boolean isNumericColumn(int colIndex);

    boolean isNumericColumn(Vector column);

    int[] getIdindexs();

    void setIdindexs(int[] idindexs);

    int getRowCount();

    int getColumnCount();

    void feedData(Object[] rawData);

    void addColumn(Object colid, Object colvalue);

    Vector<Vector> getDataVector();

    void setDataVector(Vector<Vector> dataVector);

    MetaData getMetaData();

    void setMetaData(MetaData metaData);

    AppDataModel2 getSubModelByColumnIds(Object[] colIds);

    void copyMetaInfo(AppDataModel2 model);

    AppDataModel getSubsetByColumnIds(Object[] colIds);

    AppDataModel2 getSubModelByRowIndexs(int[] rowIndexs);

    AppDataModel2 getSubModelByRowIndexs(AttributeFilter filter);

    AppDataModel getSubsetByRowIndexs(int[] rowIndexs);

    AppDataModel getAppDataModel();

    AppDataModel getAppDataModel(Object[] keys,Object[] colIds,AppDataModel model);

    void add(TableModel tm);

    void add(AppDataModel2 data);

    void save(File file);

    void saveAsTxt(File file,  String delimiter);

    void save(String file);


}
